package com.tsd;

import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

/**
 * @author Hillpool
 */
@WebListener
public class ContextFinalizer implements ServletContextListener {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("=============contextInitialized=============");
    }

    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("=============ContextFinalizer contextDestroyed=============");
        releaseQuartzThread();
        releaseSqlConnection();
    }

    /**
     * 释放定时任务线程
     * 出现类似：
     * 23-Apr-2022 21:12:34.456 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [tsdapi] appears to have started a thread named [quartzSchedulerFactoryBean_Worker-6] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
     * java.base@11.0.8/java.lang.Object.wait(Native Method)
     * org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
     */
    private void releaseQuartzThread() {
        try {
//            if (schedulerFactoryBean != null && schedulerFactoryBean.isRunning()) {
//                Scheduler job = schedulerFactoryBean.getScheduler();
//                if (job != null && job.isStarted()) {
//                    job.shutdown(false);
//                    Thread.sleep(1000);
//                }
//            }
            SchedulerFactory sf = new StdSchedulerFactory();//创建新的调度器工厂
            Scheduler scheduler = null;
            //Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler = sf.getScheduler();//获取当前进程的所有定时器线程数据
            scheduler.shutdown(true);//关闭定时器线程
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("执行关闭定时器线程！");
        } catch (Exception e) {
            e.printStackTrace();
        }
//        Scheduler job = (Scheduler) SpringBeanLoader.getSpringBean("quartzScheduler");
//        try {
//            if(job.isStarted()){
//                job.shutdown();
//                Thread.sleep(1000);
//            }
//        } catch (SchedulerException e) {
//            e.printStackTrace();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 释放数据库链接
     */
    private void releaseSqlConnection() {
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        Driver d = null;
        try {
            while (drivers.hasMoreElements()) {
                d = drivers.nextElement();
                DriverManager.deregisterDriver(d);
//                logger.info(" 消除数据库连接驱动 --> : Driver {} deregistered", d);
            }
        } catch (SQLException ex) {
            logger.error("Error: deregistering driver {} exceptionName:{} detail:{}", d, ex.getClass().getName(), ex.getMessage());
        } finally {
            AbandonedConnectionCleanupThread.uncheckedShutdown();
        }
    }
}
